package com.code.springboot3.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.code.springboot3.common.BusinessException;
import com.code.springboot3.enums.MenuEnum;
import com.code.springboot3.mapper.BigUserMapper;
import com.code.springboot3.model.dto.RoleAssignDTO;
import com.code.springboot3.model.dto.UpdatePwdDto;
import com.code.springboot3.model.dto.UserFromDto;
import com.code.springboot3.model.dto.UserUpdateInfoDto;
import com.code.springboot3.model.entity.BigUser;
import com.code.springboot3.model.vo.UserVo;
import com.code.springboot3.service.BigUserService;
import com.code.springboot3.utils.JwtUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class BigUserServiceImpl extends ServiceImpl<BigUserMapper, BigUser> implements BigUserService {
    @Autowired
    public BigUserMapper bigUserMapper;


    /**
     * 更新用户头像
     * @param avatarUrl 用户头像链接
     * @param token 用户token令牌
     * @return 0/1
     */
    @Override
    public int updateAvatar(String avatarUrl, String token) {
        Map<String, Object> map = JwtUtil.verifyToken(token);
        Integer id = (Integer) map.get("id");
        if (id == null) {
            return 0;
        }
        BigUser bigUser = bigUserMapper.selectById(id);
        bigUser.setUserPic(avatarUrl);
        return bigUserMapper.updateById(bigUser);
    }

    /**
     *  修改密码
     * @param updatePwdDto 修改密码请求体
     * @param token 用户令牌
     * @return 返回0/1
     */
    @Override
    public int updatePwd(UpdatePwdDto updatePwdDto, String token) {
        Map<String, Object> map = JwtUtil.verifyToken(token);
        Integer id = (Integer) map.get("id");
        if (id == null) {
            throw new BusinessException("请登录！");
        }
        
        BigUser bigUser = bigUserMapper.selectById(id);
        if (!Objects.equals(bigUser.getPassword(), updatePwdDto.getOld_pwd())) {
            throw new BusinessException("旧密码错误");
        }
        if (!Objects.equals(updatePwdDto.getNew_pwd(), updatePwdDto.getRe_pwd())) {
            throw new BusinessException("两次密码不一致");
        }

        // 更新密码版本
        bigUser.setPwdVersion(System.currentTimeMillis());
        bigUser.setPassword(updatePwdDto.getNew_pwd());
        bigUser.setUpdateTime(LocalDateTime.now());
        
        return bigUserMapper.updateById(bigUser);
    }

    /**
     *  用户信息更新方法
     * @param token
     * @return
     */
    @Override
    public int updateUserInfo(UserUpdateInfoDto userUpdateInfoDto, String token) {
        Map<String, Object> map = JwtUtil.verifyToken(token);
        String username = (String) map.get("username");
        Integer id = (Integer) map.get("id");
        if (id != userUpdateInfoDto.getId() || !Objects.equals(username, userUpdateInfoDto.getUsername())) {
            throw new BusinessException("更新失败");
        }

        BigUser userById = bigUserMapper.getUserById(id);
//            userById.setUsername(userUpdateInfoDto.getUsername());
        userById.setEmail(userUpdateInfoDto.getEmail());
        userById.setNickname(userUpdateInfoDto.getNickname());
        userById.setUpdateTime(LocalDateTime.now());
        return bigUserMapper.updateById(userById);
    }



    /**
     * 根据登录token获取用户信息
     * @param token
     * @return
     */
    @Override
    public UserVo getUserInfo(String token) {
        Map<String, Object> map = JwtUtil.verifyToken(token);
        Integer id = (Integer) map.get("id");
        String username = (String) map.get("username");
        BigUser user = bigUserMapper.selectById(id);
        if (Objects.equals(user.getUsername(),username)) {
            throw new BusinessException("请登录");
        }
        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(user, userVo);
        return userVo;
    }

    @Override
    public BigUser findByUsername(String username) {
        BigUser bigUser = bigUserMapper.selectByUsername(username);
        if (bigUser == null) {
            throw new BusinessException("根据用户名获取信息失败");
        }
        return bigUser;
    }

    @Override
    public UserVo register(UserFromDto userFromDto) {
        BigUser existUser = this.findByUsername(userFromDto.getUsername());
        if (existUser != null) {
            throw new BusinessException("用户名已存在");
        }
        
        String username = userFromDto.getUsername();
        String password = userFromDto.getPassword();
        BigUser bigUser = new BigUser();
        bigUser.setUsername(username);

        bigUser.setPassword(password);
        bigUser.setCreateTime(LocalDateTime.now());
        bigUser.setUpdateTime(LocalDateTime.now());
        bigUser.setPwdVersion(1L);  // 设置初始密码版本
        bigUser.setBigRole(new String[]{"user"}); // 设置默认角色
        
        int insert = bigUserMapper.insert(bigUser);
        if (insert > 0) {
//            返回脱敏信息
            return userInformationDesensitization(bigUser);
        }
        return null;
    }

    @Override
    public BigUser getUserById(int id) {
        return bigUserMapper.getUserById(id);
    }

    /**
     * 登录
     * @param userFromDto 注册登录请求DTO
     * @return  返回用户信息
     */
    @Override
    public String login(UserFromDto userFromDto) {
        // 1. 验证用户名密码
        BigUser user = this.findByUsername(userFromDto.getUsername());
        if (user == null || !user.getPassword().equals(userFromDto.getPassword())) {
            throw new BusinessException("用户名或密码错误");
        }
        
        // 2. 生成Token
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", user.getId());
        claims.put("username", user.getUsername());
        return JwtUtil.generateToken(claims, user.getPwdVersion());
    }

    /**
     * 信息脱敏
     * @param user 用户实体
     * @return 返回脱敏信息
     */
    @Override
    public UserVo userInformationDesensitization(BigUser user) {
        UserVo userVo = new UserVo();
        //拷贝属性
        BeanUtils.copyProperties(user,userVo);
        return userVo;
    }

    @Override
    public void assignRole(RoleAssignDTO dto) {
        BigUser user = bigUserMapper.selectById(dto.getId());
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        // 验证角色是否有效
        for (String role : dto.getBigRole()) {
            if (MenuEnum.getByCode(role) == null) {
                throw new BusinessException("无效的角色代码: " + role);
            }
        }
        
        user.setBigRole(dto.getBigRole());
        user.setUpdateTime(LocalDateTime.now());
        bigUserMapper.updateById(user);
    }

    /**
     * 获取到UserVo的list列表
     * @return 返回UserVo的list列表
     */
    public List<UserVo> getUserList() {
        // 从 BigUserService 获取 List<BigUser>
        List<BigUser> bigUserList = this.list();

        // 使用 Stream 进行转换
        return bigUserList.stream()
                .map(this::convertToUserVo)  // 调用转换方法
                .collect(Collectors.toList());
    }


    // 转换方法：将 BigUser 转换为 UserVo
    private UserVo convertToUserVo(BigUser bigUser) {
        UserVo userVo = new UserVo();
        // 假设 UserVo 和 BigUser 有一些相同的字段，手动映射字段
        userVo.setId(bigUser.getId());
        userVo.setUsername(bigUser.getUsername());
        userVo.setEmail(bigUser.getEmail());
        // 添加其他字段映射
        return userVo;
    }

}
